package com.cn.xiaonuo.slbfinances.slborders.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cn.xiaonuo.common.entity.BusinessMessage;
import com.cn.xiaonuo.common.utils.StringUtils;
import com.cn.xiaonuo.dbs.core.annotation.DataSource;
import com.cn.xiaonuo.slbfinances.slborders.entity.SlScoreWalletRecord;
import com.cn.xiaonuo.slbfinances.slborders.entity.SlScoreWithdraw;
import com.cn.xiaonuo.slbfinances.slborders.mapper.SlScoreWalletMapper;
import com.cn.xiaonuo.slbfinances.slborders.mapper.SlScoreWalletRecordMapper;
import com.cn.xiaonuo.slbfinances.slborders.mapper.SlScoreWithdrawMapper;
import com.cn.xiaonuo.slbfinances.slborders.param.AuditParam;
import com.cn.xiaonuo.slbfinances.slborders.param.PaymentParam;
import com.cn.xiaonuo.slbfinances.slborders.param.SlScoreWithdrawParam;
import com.cn.xiaonuo.slbfinances.slborders.service.SlScoreWithdrawService;
import com.cn.xiaonuo.slbfinances.slborders.utils.Integer2BigdecimalUtils;
import com.cn.xiaonuo.slbfinances.slborders.vo.SlScoreWithdrawVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author Admin
 * @description 针对表【sl_score_withdraw(业绩钱包提现记录)】的数据库操作Service实现
 * @createDate 2023-07-05 11:24:30
 */
@Service
@Slf4j
public class SlScoreWithdrawServiceImpl extends ServiceImpl<SlScoreWithdrawMapper, SlScoreWithdraw>
        implements SlScoreWithdrawService {

    @Autowired
    private SlScoreWithdrawMapper slScoreWithdrawMapper;
    @Autowired
    private SlScoreWalletMapper slScoreWalletMapper;
    @Autowired
    private SlScoreWalletRecordMapper slScoreWalletRecordMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    @DataSource(name = "jyb_soole_data_hn")
    public BusinessMessage list(SlScoreWithdrawParam param) {
        BusinessMessage message = new BusinessMessage();
        PageHelper.startPage(param.getPageNo(), param.getPageSize());
        List<SlScoreWithdraw> list = slScoreWithdrawMapper.list(param);
        List<SlScoreWithdrawVo> voList = new ArrayList<>();
        for (SlScoreWithdraw slScoreWithdraw : list) {
            SlScoreWithdrawVo slScoreWithdrawVo = new SlScoreWithdrawVo();
            BeanUtil.copyProperties(slScoreWithdraw, slScoreWithdrawVo, "withdrawMoney", "fee", "remitAmount");
            //四舍五入,保留2位小数
            slScoreWithdrawVo.setWithdrawMoney(Integer2BigdecimalUtils.round(slScoreWithdraw.getWithdrawMoney()));
            slScoreWithdrawVo.setFee(Integer2BigdecimalUtils.round(slScoreWithdraw.getFee()));
            slScoreWithdrawVo.setRemitAmount(Integer2BigdecimalUtils.round(slScoreWithdraw.getRemitAmount()));
            voList.add(slScoreWithdrawVo);
        }
        message.setData(new PageInfo<>(voList));
        message.setSuccess(true);
        return message;
    }

    @Override
    @DataSource(name = "jyb_soole_data_hn")
    @Transactional(rollbackFor = Exception.class)
    public BusinessMessage audit(AuditParam param) {
        BusinessMessage message = new BusinessMessage();
        //参数校验
        Integer status = param.getStatus();
        if (status == null) {
            message.setMessage("status不能为空");
            message.setSuccess(false);
            return message;
        }
        Integer id = param.getId();
        if (id == null) {
            message.setMessage("提现id不能为空");
            message.setSuccess(false);
            return message;
        }
        BigDecimal withdrawMoney = param.getWithdrawMoney();
        if (withdrawMoney == null) {
            message.setMessage("提现金额不能为空");
            message.setSuccess(false);
            return message;
        }
        Integer walletId = param.getWalletId();
        if (walletId == null) {
            message.setMessage("钱包id不能为空");
            message.setSuccess(false);
            return message;
        }
        String withdrawNo = param.getWithdrawNo();
        if (StringUtils.isEmpty(withdrawNo)) {
            message.setMessage("提现编号不能为空");
            message.setSuccess(false);
            return message;
        }
        Integer userId = param.getUserId();
        if (userId == null) {
            message.setMessage("userId不能为空");
            message.setSuccess(false);
            return message;
        }
        String key = "SLB_WITHDRAW_" + param.getWalletId();
        try {
            Boolean lock = redisTemplate.opsForValue().setIfAbsent(key, 1, 5, TimeUnit.MINUTES);
            if (!lock) {
                message.setMessage("正在提现，请勿重复提交");
                message.setCode("-1");
                message.setSuccess(false);
                log.info("正在提现，请勿重复提交{}", key);
                return message;
            }
            //同意提现
            if (param.getStatus() == 1) {
                SlScoreWithdraw slScoreWithdraw = new SlScoreWithdraw();
                slScoreWithdraw.setId(param.getId());
                slScoreWithdraw.setStatus(param.getStatus());
                slScoreWithdrawMapper.updateById(slScoreWithdraw);
                message.setMessage("同意提现,操作成功");
                log.info("同意提现,操作成功");
            }
            //拒绝提现
            if (param.getStatus() == 2) {
                SlScoreWithdraw slScoreWithdraw = new SlScoreWithdraw();
                slScoreWithdraw.setId(param.getId());
                slScoreWithdraw.setStatus(param.getStatus());
                slScoreWithdrawMapper.updateById(slScoreWithdraw);
                //钱包余额增加
                BigDecimal oneHundred = new BigDecimal("100");
                //元转换成分
                int money = param.getWithdrawMoney().multiply(oneHundred).intValue();
                slScoreWalletMapper.reduceAvailableBalance(walletId, userId, money);
                //生成流水
                SlScoreWalletRecord slScoreWalletRecord = new SlScoreWalletRecord();
                slScoreWalletRecord.setNo(param.getWithdrawNo());
                slScoreWalletRecord.setWalletId(param.getWalletId());
                slScoreWalletRecord.setUserId(param.getUserId());
                slScoreWalletRecord.setSource(1);//流水来源 0.邀请业绩 1.提现
                slScoreWalletRecord.setType(0);//流水类型 0.入账 1.出账
                slScoreWalletRecord.setRecordMoney(param.getWithdrawMoney().multiply(new BigDecimal("100")).intValue());
                slScoreWalletRecord.setRemark("拒绝提现理由:" + param.getRemark() + ",共" + param.getWithdrawMoney() + "元");
                slScoreWalletRecord.setCreatedTime(new Date());
                slScoreWalletRecord.setUpdatedTime(new Date());
//                slScoreWalletRecordMapper.insert(slScoreWalletRecord);
                slScoreWalletRecordMapper.addScoreWalletRecord(slScoreWalletRecord);
                message.setMessage("拒绝提现,操作成功");
                log.info("拒绝提现,操作成功");
            }
        } catch (Exception e) {
            message.setSuccess(false);
            message.setMessage("提现操作失败");
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            e.printStackTrace();
        } finally {
            //释放锁资源
            redisTemplate.delete(key);
        }
        message.setSuccess(true);
        return message;
    }

    @Override
    @DataSource(name = "jyb_soole_data_hn")
    public BusinessMessage payment(PaymentParam param) {
        BusinessMessage message = new BusinessMessage();
        //参数校验
        Integer id = param.getId();
        if (id == null) {
            message.setMessage("提现id不能为空");
            message.setSuccess(false);
            return message;
        }
        //更改提现状态
        SlScoreWithdraw slScoreWithdraw = new SlScoreWithdraw();
        slScoreWithdraw.setId(param.getId());
        slScoreWithdraw.setStatus(1);//提现状态 0.未打款 1.已打款'
        slScoreWithdraw.setUpdatedTime(new Date());
        slScoreWithdrawMapper.updateById(slScoreWithdraw);
        log.info("打款,操作成功");
        message.setMessage("打款,操作成功");
        message.setSuccess(true);
        return message;
    }
}




